#include "PrecompiledHeader_Engineer.h"
#include "WTerrain.h"

/*--------------------------------------------------------------------------*/

WTerrain::WTerrain()
{

}

/*--------------------------------------------------------------------------*/

WTerrain::~WTerrain()
{

}

/*--------------------------------------------------------------------------*/

void WTerrain::GetHeight(glm::vec3& v) const
{
	unsigned int colorValue1 = this->m_heightmap->GetPixelValue(glm::ivec2(v.x, v.y));
	unsigned int colorValue2 = this->m_heightmap->GetPixelValue(glm::ivec2(v.x + 1, v.y));
	unsigned int colorValue3 = this->m_heightmap->GetPixelValue(glm::ivec2(v.x + 1, v.y + 1));
	unsigned int colorValue4 = this->m_heightmap->GetPixelValue(glm::ivec2(v.x, v.y + 1));

	v.z = 0.0f;

	v.z += ((colorValue1 & 0x00ff0000) >> 16) * 0.6f + 0.63f;
	v.z += ((colorValue2 & 0x00ff0000) >> 16) * 0.6f + 0.63f;
	v.z += ((colorValue3 & 0x00ff0000) >> 16) * 0.6f + 0.63f;
	v.z += ((colorValue4 & 0x00ff0000) >> 16) * 0.6f + 0.63f;

	v.z *= 0.25f;
}

/*--------------------------------------------------------------------------*/

void WTerrain::GetNormal(const glm::vec3& v, glm::vec3& normal) const
{
	float offset = 1.5f;
	glm::vec3 a[4];

	a[0] = glm::vec3(v.x - offset, v.y, 0.0f);
	a[1] = glm::vec3(v.x + offset, v.y, 0.0f);
	a[2] = glm::vec3(v.x, v.y - offset, 0.0f);
	a[3] = glm::vec3(v.x, v.y + offset, 0.0f);

	this->GetHeight(a[0]);
	this->GetHeight(a[1]);
	this->GetHeight(a[2]);
	this->GetHeight(a[3]);

	glm::vec3 d[2];

	d[0] = glm::normalize(a[0] - a[1]);
	d[1] = glm::normalize(a[2] - a[3]);

	normal = glm::normalize(glm::cross(d[0], d[1]));
}

/*--------------------------------------------------------------------------*/

float WTerrain::GetJunglePropability(const glm::vec3& v) const
{
	unsigned int colorValue1 = this->m_detailmap->GetPixelValue(glm::ivec2(v.x, v.y));

	return (colorValue1 & 0x000000ff) / 255.0f;
}

/*--------------------------------------------------------------------------*/

float WTerrain::GetRadiationLevel(const glm::vec3& v) const
{
	unsigned int colorValue1 = this->m_detailmap->GetPixelValue(glm::ivec2(v.x, v.y));

	float f = ((colorValue1 & 0x0000ff00 >> 8) / 255.0f);

	f = f * f * f;

	if (f < 0.4f)
	{
		return 0.0f;
	}
	else
	{
		return f;
	}
}

/*--------------------------------------------------------------------------*/

void WTerrain::OnLevelLoad(const std::string& level)
{
	this->m_heightmap = new SDLTexture(level + ".png");
	this->m_detailmap = new SDLTexture(level + "_detail.png");
	this->m_heightmapOGL = new Texture(level + ".png");

	this->m_quads = new Quad*[400];

	for (int x = 0; x < 20; ++x)
	{
		for (int y = 0; y < 20; ++y)
		{
			this->m_quads[20 * y + x] = new Quad(glm::vec2(CWorld::m_quadSize * 0.5f + x * CWorld::m_quadSize, CWorld::m_quadSize * 0.5f + y * CWorld::m_quadSize));
			this->m_quads[20 * y + x]->QuadStart();
		}
	}
}

/*--------------------------------------------------------------------------*/

void WTerrain::OnLevelUnload()
{
	for (unsigned int i = 0; i < 400; ++i)
	{
		CTree::getInstance()->DeleteObject(this->m_quads[i]);
	}

//	delete this->m_heightmap;
//	delete this->m_detailmap;
//	delete this->m_heightmapOGL;
}

/*--------------------------------------------------------------------------*/

void WTerrain::OnLevelCalc()
{

}

/*--------------------------------------------------------------------------*/

const Texture* WTerrain::GetHeightMap() const
{
	return this->m_heightmapOGL;
}

/*--------------------------------------------------------------------------*/

Quad* WTerrain::GetQuad(const glm::vec3& pos) const
{
	return this->m_quads[((int)((pos.y - 0.5f) / CWorld::m_quadSize)) * 20 + ((int)((pos.x - 0.5f) / CWorld::m_quadSize)) ];
}

/*--------------------------------------------------------------------------*/

bool WTerrain::IsCollision(const glm::vec3& pos) const
{
	Quad* q = this->GetQuad(pos);
	glm::vec2 ptc = glm::vec2(pos.x - q->GetPosition().x, pos.y - q->GetPosition().y);

	return q->IsCollision(ptc);
}

/*--------------------------------------------------------------------------*/